// |**| Opcon|OperationMango|**|Opcon|OperationMango|**|
// |**| Source Code for the FPS Operation Mango     |**|
// |**| Opcon|OperationMango|**|Opcon|OperationMango|**|

using System;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
using System.Drawing;
using System.Windows.Forms;

namespace OperationMango
{


	public class MovementController : CameraBase
	{
		
		MouseDevice m_Mouse;
		KeyboardDevice m_Keyboard;
		
		bool m_LMouseButtonDown;
		
		Vector2 m_MousePositionOnDown;
		Vector2 m_MousePosition;
		
		float m_XRotationOnDown;
		float m_XRotation;
		float m_TargetXRotation;
		float m_YRotationOnDown;
		float m_YRotation;
		float m_TargetYRotation;
		
		float m_MaxSpeed;
		float m_CurrentSpeed;
		
		Point m_MousePrevious;
		Point m_MouseDelta;
		protected Rectangle m_ClientRectangle;
		protected Rectangle m_Bounds;
		
		Point WindowCenter
		{
		    get
		    {
		        return new Point(
		             (m_Bounds.Left + m_Bounds.Right) / 2,
		            (m_Bounds.Top + m_Bounds.Bottom) / 2);
		    }
		}

		
		//------------------------------------------------------------------------------------------------
		
		public MovementController (Vector3 intialposition, Vector3 intialtarget, KeyboardDevice k, MouseDevice m, Rectangle client, Rectangle bounds)
		{
			SetupLocalVariables (k, m, intialposition, intialtarget);
			UpdateBounds(client, bounds);
			// Move mouse to center of window to ensure correct deltas from the very start
			ResetMouse();
			m_MousePrevious = new Point(m_Mouse.X, m_Mouse.Y);
		}

		void ResetMouse ()
		{
			Cursor.Position = WindowCenter;

		}

		
		protected void SetupLocalVariables (KeyboardDevice k, MouseDevice m, Vector3 intialposition, Vector3 intialtarget)
		{
			m_Keyboard = k;
			m_CameraMatrix = Matrix4.LookAt (intialposition, intialtarget, Vector3.UnitY);
			m_Mouse = m;
			m_TargetXRotation = m_TargetYRotation = 0.0f;
			m_XRotation = m_YRotation = 0.0f;
			m_LMouseButtonDown = false;
			m_RotationMatrix = m_TranslationMatrix = m_TemporaryMatrix = m_PreviousCameraMatrix = Matrix4.Identity;
		}
		
		public void UpdateBounds(Rectangle client, Rectangle bounds)
		{
			m_Bounds = bounds;
			m_ClientRectangle = client;
		}
		
		//------------------------------------------------------------------------------------------------
		
		
		public void Update (FrameEventArgs e)
		{
			if (m_Keyboard[Key.W] || m_Keyboard[Key.S])
			{
				
			}
			
			if (m_Keyboard[Key.A] || m_Keyboard[Key.D])
			{
				
			}
			
			
			HandleRotation ();
			
			FinalizeMatrices();
			
			UpdateMatrices();
			
			//Console.WriteLine ("m_MouseDelta={0}", m_MouseDelta);
		}
		
		protected void HandleRotation ()
		{
			CalculateMouseDelta();
			//ResetMouse();
			RotateCameraX((float)(m_MouseDelta.X * 0.01));
			Console.WriteLine ("Rotation X = " + m_RotationX);
			RotateCameraY((float)(m_MouseDelta.Y * 0.01));
			Console.WriteLine("Rotation Y = " + m_RotationY);
			
			CombineRotations();
			Console.WriteLine("Rotation Combined = " + m_Rotation);
			
			RotateCamera(ref m_Rotation);
			
			Console.WriteLine("Rotation Matrix = " + m_RotationMatrix);
		}

		
		// Calculates how far the mouse has moved since the last call to this method
		void CalculateMouseDelta()
		{
		    Point m_MouseCurrent = new Point(m_Mouse.X, m_Mouse.Y);
			
		    m_MouseDelta = new Point(
		        m_MouseCurrent.X - m_MousePrevious.X,
		        m_MouseCurrent.Y - m_MousePrevious.Y);
		    m_MousePrevious = m_MouseCurrent;
		}
		
		
		
		
	}
}
